import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import java.awt.*;
import java.util.HashMap;
import java.util.List;
import java.util.Iterator;

import org.dom4j.*;
import org.dom4j.io.*;
import Common.Game;

public class GameRoom extends JFrame{
    final String LOGO_PATH = "./images/logo.png";
    final String APP_TITLE = "小游戏大全";
    final String APP_DESCRIPTION = "汇集各类小游戏，供各位同学学习玩耍！";
    final String APP_AUTHOR = "Java程序设计课程组及全体同学";
    final String APP_ORG = "沈阳北软信息职业技术学院";
    final String RELEASE_DATE = "2022.04.09";

    HashMap<String, List<Attribute>> games = new HashMap<String, List<Attribute>>();

    String gameInfo = "<html><body><h3 style=\"text-align:center\">%s</h3>" +
            "<p style=\"word-wrap:break-word\">%s</p>" +
            "<div style=\"text-align:right;margin-top:20px;\">" +
            "<p>%s</p><p>%s</p><p>%s</p></div></body></html>";

    String selectedGameName;

    public GameRoom() {
        this.loadGames();

        this.setLocation(400, 100);
        this.setSize(512, 512);
        this.setTitle(APP_TITLE);
        this.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
        Container container = this.getContentPane();

        JScrollPane gameListPane = new JScrollPane();
        JList gameList = new JList(this.games.keySet().toArray(new String[this.games.size()]));
        gameListPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        gameListPane.getViewport().setView(gameList);
        gameListPane.setPreferredSize(new Dimension(240, 460));
        container.add(gameListPane);

        JPanel gameInfoPanel = new JPanel();
        gameInfoPanel.setPreferredSize(new Dimension(240, 460));
        gameInfoPanel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
        ImageIcon icon = new ImageIcon(LOGO_PATH);
        JLabel logo = new JLabel(icon, JLabel.CENTER);
        gameInfoPanel.add(logo);

        JLabel description = new JLabel();
        description.setText(String.format(this.gameInfo, APP_TITLE, APP_DESCRIPTION,
                APP_AUTHOR, APP_ORG, RELEASE_DATE));
        gameInfoPanel.add(description);
        container.add(gameInfoPanel);

        gameList.addListSelectionListener((ListSelectionEvent e) -> {
            if(!e.getValueIsAdjusting()){
                this.selectedGameName = gameList.getSelectedValue().toString();
                gameInfoPanel.removeAll();
                gameInfoPanel.revalidate();
                List<Attribute> gameAttributes = this.games.get(this.selectedGameName);
                ImageIcon gameIcon = new ImageIcon(gameAttributes.get(4).getValue());
                JLabel gameLogo = new JLabel(gameIcon, JLabel.CENTER);
                gameInfoPanel.add(gameLogo);
                JButton gameStartBtn = new JButton("开始游戏");
                gameStartBtn.addActionListener(event -> {
                    String packageName = gameAttributes.get(5).getValue();
                    String entranceClass = gameAttributes.get(8).getValue();
                    try {
                        Class c = Class.forName(packageName+"."+entranceClass);
                        Game game = (Game)c.newInstance();
                        game.run();
                    } catch (ClassNotFoundException classNotFoundException) {
                        JOptionPane.showMessageDialog(this, "找不到该游戏",
                                "错误", JOptionPane.ERROR_MESSAGE);
                    } catch (IllegalAccessException illegalAccessException) {
                        JOptionPane.showMessageDialog(this, "无法访问该游戏",
                                "错误", JOptionPane.ERROR_MESSAGE);
                    } catch (InstantiationException instantiationException) {
                        JOptionPane.showMessageDialog(this, "无法创建游戏实例",
                                "错误", JOptionPane.ERROR_MESSAGE);
                    }
                });
                gameInfoPanel.add(gameStartBtn);
                JLabel gameDescription = new JLabel();
                gameDescription.setPreferredSize(new Dimension(240, 230));
                gameDescription.setText(String.format(this.gameInfo,
                        gameAttributes.get(1).getValue(),
                        gameAttributes.get(6).getValue(),
                        gameAttributes.get(3).getValue(),
                        gameAttributes.get(2).getValue(),
                        gameAttributes.get(7).getValue()));
                gameInfoPanel.add(gameDescription);
                gameInfoPanel.updateUI();
            }
        });

        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void loadGames(){
        SAXReader saxr = new SAXReader();
        try {
            Document document = saxr.read("GameRoom.xml");
            Element root = document.getRootElement();
            Iterator games = root.elementIterator();
            while(games.hasNext()){
                Element game = (Element)games.next();
                String name = game.attributeValue("name");
                List<Attribute> attributes = game.attributes();
                this.games.put(name, attributes);
            }
        } catch (DocumentException e) {
            JOptionPane.showMessageDialog(this, "游戏清单解析失败！",
                    "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    public static void main(String [] args){
        GameRoom gr = new GameRoom();
    }
}